package adminlte.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.oauth2.client.endpoint.DefaultAuthorizationCodeTokenResponseClient;
import org.springframework.security.oauth2.client.endpoint.OAuth2AccessTokenResponseClient;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository;
import org.springframework.security.oauth2.client.userinfo.DefaultOAuth2UserService;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserRequest;
import org.springframework.security.oauth2.client.userinfo.OAuth2UserService;
import org.springframework.security.oauth2.core.AuthorizationGrantType;
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
import org.springframework.security.oauth2.core.oidc.IdTokenClaimNames;
import org.springframework.security.oauth2.core.user.OAuth2User;

/**
 * OAuth2登陆配置
 * @see org.springframework.security.config.annotation.web.configurers.oauth2.client.OAuth2LoginConfigurer
 * @author ZHUFEIFEI
 */
@Configuration
public class OAuth2LoginConfig {

    @EnableWebSecurity(debug = true)
    public static class OAuth2LoginSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests()
                    .anyRequest().authenticated()
                    .and()
                    .oauth2Login()
                    //默认OAuth2LoginAuthenticationFilter /login/oauth2/code/*
                    //可以自定义
                    .redirectionEndpoint().baseUri("/login/oauth2/callback/*")
            ;
            http.sessionManagement().maximumSessions(1);
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            super.configure(auth);
        }
    }

    @Bean
    public ClientRegistrationRepository clientRegistrationRepositroy() {
        return new InMemoryClientRegistrationRepository(this.clientRegistration());
    }

    private ClientRegistration clientRegistration() {
        //该部分配置可以写到application.yml中，见本类末尾 OAuth2ClientProperties
        return ClientRegistration.withRegistrationId("adminlteClient1")
                .clientId("adminlteClient1")
                .clientSecret("123456")
                .clientAuthenticationMethod(ClientAuthenticationMethod.POST)
                .authorizationGrantType(AuthorizationGrantType.AUTHORIZATION_CODE)
//                .redirectUriTemplate("{baseUrl}/login/oauth2/code/{registrationId}")
                //回调地址不需要有controller对应，在filter中有处理
                .redirectUriTemplate("{baseUrl}/login/oauth2/callback/{registrationId}")
                .scope("email", "phone")
                .authorizationUri("http://192.168.72.115:8088/oauth/authorize")
                .tokenUri("http://192.168.72.115:8088/oauth/token")
                .userInfoUri("http://192.168.72.115:8088/user/info")
                //userNameAttributeName指的是通过userInfoUri获取到的认证信息中包含用户登录名的属性名称
                //默认userInfoUri返回Principal的json体内该属性名称为name
                //在DefaultOAuth2User构造函数中有验证返回的用户信息中是否包含配置的属性名
                .userNameAttributeName("name")
                .jwkSetUri("")
                .clientName("adminlte")
                .build();
    }
}

/**
 spring:
    security:
        oauth2:
            client:
                registration:
                    client-1:
                         client-id: ${APP-CLIENT-ID}
                         client-secret: ${APP-CLIENT-SECRET}
                         client-name: aaa
                         provider: oauth2server
                         scope: email
                         redirect-uri-template: http://localhost:8080/login/oauth2/code/github
                         client-authentication-method: basic
                         authorization-grant-type: authorization_code
                 provider:
                    oauth2server:
                         authorization-uri: http://localhost:8088/oauth/authorize
                         token-uri: http://localhost:8088/oauth/token
                         userInfoUri: http://localhost:8088/user/info
                         userNameAttribute: username
 **/